package com.itheima.a02.BeanFactory实现One;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*
* BeanFactory演示1
* */
public class TestBeanFactoryOne {
    public static void main(String[] args) {
        /*DefaultListableBeanFactory是BeanFactory的重要实现*/
        /*下面就是创建了一个spring核心容器beanFactory*/
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        // bean 的定义（class类型, scope单例/多例, 初始化方法, 销毁方法）
        /*对bean进行定义，然后注册一个bean Definition对象到容器里面*/
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("config", beanDefinition);

        // 给 BeanFactory 添加一些常用的后处理器，其实就是对beanFactory功能的扩展
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        /*根据后处理器的类型获取多个bean,也就是下面的bean工厂后处理器。*/
        /*拿到每一个bean工厂处理器并执行它，也就是调用postProcessBeanFactory这个方法*/
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        /*添加bean后置处理器，解决@Autowired、@Resource问题*/
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

        Bean2 bean2 = beanFactory.getBean(Bean1.class).getBean2();
        System.out.println("bean2结果："+bean2);

        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }

    }

    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }
        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }

    }

    static class Bean1 {
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);
        public Bean1() {
            log.debug("构造 Bean1()");
        }
        @Autowired
        private Bean2 bean2;
        public Bean2 getBean2() {
            return bean2;
        }
    }

    static class Bean2 {
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);
        public Bean2() {
            log.debug("构造 Bean2()");
        }
    }

}
